// utils/streamRequest.js
import { getToken } from '@/utils/auth'
import { ElNotification, ElMessage, ElMessageBox } from 'element-plus'
import errorCode from '@/utils/errorCode'
import { tansParams } from '@/utils/ruoyi'
import cache from '@/plugins/cache'
import useUserStore from '@/store/modules/user'

// 是否显示重新登录
let isRelogin = { show: false }

// 获取基础URL
const baseURL = import.meta.env.VITE_APP_BASE_API

export const streamRequest = async (url, options = {}) => {
  // 处理请求配置
  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), options.timeout || 100000)
  
  // 合并默认配置
  const defaultOptions = {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': getToken() ? `Bearer ${getToken()}` : ''
    },
    signal: controller.signal
  }

  // 处理 GET 请求参数
  if (options.method === 'GET' && options.params) {
    url += '?' + tansParams(options.params)
    delete options.params
  }

  // 处理重复提交（POST/PUT 方法）
  if (!options.isRepeatSubmit && (options.method === 'POST' || options.method === 'PUT')) {
    const requestObj = {
      url,
      data: typeof options.body === 'object' ? JSON.stringify(options.body) : options.body,
      time: new Date().getTime()
    }
    
    const requestSize = JSON.stringify(requestObj).length
    const limitSize = 5 * 1024 * 1024 // 5MB
    
    if (requestSize < limitSize) {
      const sessionObj = cache.session.getJSON('sessionObj') || {}
      
      if (sessionObj.url === url && 
          sessionObj.data === requestObj.data && 
          requestObj.time - sessionObj.time < 1000) {
        const message = '数据正在处理，请勿重复提交'
        return Promise.reject(new Error(message))
      }
      
      cache.session.setJSON('sessionObj', requestObj)
    }
  }

  // 合并配置选项
  const mergedOptions = {
    ...defaultOptions,
    ...options,
    headers: {
      ...defaultOptions.headers,
      ...(options.headers || {})
    }
  }

  try {
    // 构建完整URL
    const fullUrl = url.startsWith('http') ? url : `${baseURL}${url}`
    
    // 发送请求
    const response = await fetch(fullUrl, mergedOptions)
    clearTimeout(timeoutId)
    
    // 处理非200响应
    if (!response.ok) {
      // 尝试解析错误响应
      let errorData = {}
      try {
        errorData = await response.clone().json()
      } catch {
        try {
          errorData = { msg: await response.clone().text() }
        } catch {
          errorData = { msg: '未知错误' }
        }
      }
      
      const status = response.status
      const errorMsg = errorData.msg || errorCode[status] || '请求失败'
      
      // 特殊处理401未授权
      if (status === 401) {
        if (!isRelogin.show) {
          isRelogin.show = true
          ElMessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            isRelogin.show = false
            useUserStore().logOut().then(() => {
              location.href = '/index'
            })
          }).catch(() => {
            isRelogin.show = false
          })
        }
        return Promise.reject('无效的会话，或者会话已过期，请重新登录。')
      } 
      // 其他错误状态处理
      else if (status >= 500) {
        ElMessage({ message: errorMsg, type: 'error' })
      } else if (status === 601) {
        ElMessage({ message: errorMsg, type: 'warning' })
      } else {
        ElNotification.error({ title: errorMsg })
      }
      
      throw new Error(`HTTP error! status: ${status}`)
    }
    
    return response
  } catch (error) {
    clearTimeout(timeoutId)
    
    // 错误信息转换
    let message = error.message
    if (error.name === 'AbortError') {
      message = "请求超时"
    } else if (message.includes('Failed to fetch')) {
      message = "后端接口连接异常"
    } else if (message.includes('NetworkError')) {
      message = "网络错误"
    } else if (message.includes('Request failed with status code')) {
      message = `系统接口${message.substr(-3)}异常`
    }
    
    ElMessage({ message, type: 'error', duration: 5000 })
    throw error
  }
}

// 流式读取辅助函数
export const readStream = async (response, onData, onComplete, onError) => {
  const reader = response.body.getReader()
  const decoder = new TextDecoder()
  let result = ''

  try {
    while (true) {
      const { value, done } = await reader.read()
      if (done) break
      
      const chunk = decoder.decode(value, { stream: true })
      const lines = chunk.split('\n\n').filter(line => line.trim())
      
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const content = line.replace('data: ', '')
          
          // 处理特殊控制消息
          if (content === '[DONE]') return onComplete?.()
          if (content.startsWith('[ERROR]')) {
            throw new Error(content.substring(7))
          }
          
          result += content
          onData?.(content, result)
        }
      }
    }
    
    onComplete?.()
  } catch (error) {
    onError?.(error)
    throw error
  }
}